/**
 * Copyright(c) 2013 Jade Techonologies, Ltd.
 *
 * History:
 *   2011-5-25 14:46:21 Created by sky
 */
package com.jade.bss.base.customer;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.util.PagingList;

/**
 * 客户管理接口，包括新增客户、删除客户以及修改客户信息等等。
 *
 * @author sky
 * @version 1.0 2011-5-25 14:46:21
 */
public interface CustomerManager
{
    /**
     * 添加一个客户
     *
     * @param customer 客户对象
     * @return 客户标识
     * @throws CustomerException 客户名称冲突
     */
    public long addCustomer(Customer customer)
            throws CustomerException;

    /**
     * 根据客户标识获取客户信息
     * <p/>
     * 如果客户不存在，返回null
     *
     * @param id 客户标识
     * @return 客户对象
     */
    public Customer getCustomer(long id);

    /**
     * 根据客户标志获取客户信息
     *
     * @param id 客户标志
     * @return 客户对象
     * @throws CustomerException 客户不存在
     */
    public Customer loadCustomer(long id)
            throws CustomerException;

    /**
     * 根据客户名称获取客户信息．
     *
     * @param type 客户类型，type为NULL时要求不同类型的客户其名称也要保持唯一。
     * @param name 客户名称
     * @return 客户对象
     */
    public Customer getCustomer(String type, String name);

    public Customer getCustomer(String name);

    /**
     * 修改客户状态
     * status 状态
     *
     * @param status 新的状态
     * @param ids    客户id
     * @throws CustomerException 客户名称冲突
     */
    public void updateStatus(int status, long... ids)
            throws CustomerException;

    /**
     * 修改客户基本资料信息，仅仅包括名称、手机、邮件地址等信息。
     *
     * @param customer 客户资料
     * @throws CustomerException 客户名称冲突
     */
    public void updateCustomer(Customer customer)
            throws CustomerException;

    /**
     * 根据用户名和密码校验用户。
     *
     * @param type 客户类型，type为NULL时要求不同类型的客户其名称也要保持唯一。
     * @param name     用户名称
     * @param password 用户密码
     * @return 客户信息
     * @throws CustomerException 密码错误；客户不存在
     */
    public Customer validateCustomer(String type, String name, String password)
            throws CustomerException;

    public Customer validateCustomer(String name, String password)
            throws CustomerException;

    /**
     * 校验客户密码。
     *
     * @param encPassword 加密后密码
     * @param password    待校验的密码
     * @return 密码匹配返回true;否则返回false
     */
    public boolean validatePassword(String encPassword, String password);

    /**
     * 修改客户密码（根据id,需要校验旧密码）
     *
     * @param id          客户标识
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @throws CustomerException 异常 客户不存在/旧密码不正确
     */
    public void modifyPassword(long id, String oldPassword, String newPassword)
            throws CustomerException;

    /**
     * 重置客户密码（根据id,不需要校验旧密码）
     *
     * @param id       客户标识
     * @param password 新密码
     * @throws CustomerException 异常
     */
    public void resetPassword(long id, String password)
            throws CustomerException;

    /**
     * 查询客户的信息,获取客户列表。infoClasses表示要获取的扩展信息类，为null或者空将不获取扩展信息类型。
     * Criteria条件中各个项的名称必须为 customer.name 或者 latestLoginInfo.name 这种格式。
     *
     * @param criteria    参数
     * @param infoClasses 扩展信息类
     * @return 客户列表
     */
    public PagingList<Customer> queryCustomer(Criteria criteria, Class... infoClasses);

    /**
     * 根据距离排序来查询客户的信息,获取客户列表。infoClasses表示要获取的扩展信息类，为null或者空将不获取扩展信息类型。
     * 此方法仅针对带有EnterpriseInfo扩展信息的客户。
     *
     * @param criteria    参数
     * @param infos 扩展信息类
     * @return 客户列表
     */
    public PagingList<Customer> querySortDistance(double lat, double lng, double distance, Criteria criteria, Class... infos);

    /**
     * 批量删除客户
     *
     * @param ids 客户标识数组
     * @throws CustomerException 异常
     */
    public void removeCustomer(long... ids)
            throws CustomerException;

    /**
     * 获取一个客户某一类型的扩展信息。
     *
     * @param customerId 客户标识。
     * @param infoClass  扩展信息类。
     * @return 客户扩展信息。
     */
    public <Info extends CustomerInfo> Info getExtendedInfo(long customerId, Class infoClass);

    /**
     * 获取一个客户所有的扩展信息。
     *
     * @param customerId  客户标识。
     * @param infoClasses 要删除的类型。
     * @return 客户所有的扩展信息。
     */
    public Map<Class, CustomerInfo> getExtendedInfos(long customerId, Class... infoClasses);

    /**
     * 更新客户的扩展信息。
     *
     * @param infos 客户的扩展信息。
     * @throws CustomerException 更新扩展信息异常，可能是持久化错误
     */
    public void updateExtendedInfo(CustomerInfo... infos)
            throws CustomerException;

    /**
     * 删除客户的指定类型的扩展信息。
     *
     * @param customerId  客户标识。
     * @param infoClasses 扩展信息类列表。
     * @throws CustomerException 删除扩展信息异常，可能是持久化错误
     */
    public void removeExtendedInfos(long customerId, Class... infoClasses)
            throws CustomerException;

    /**
     * 根据类型获取客户数量。
     *
     * @param type 客户类型
     * @return 客户数量
     */
    public long getCustomerCountByType(String type);

    //public List<String> listTopTag(int length);

    public List<String> listTopTag(Criteria criteria);

    /**
     * 获取某一种用户在具体时间段内的注册数量，时间为空则获去所有
     * @param beginDate
     * @param endDate
     * @param type
     * @return
     */
    public long getUserCount(Date beginDate,Date endDate,String type);

}
